package machineLearning;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import machineLearning.SentenceExampleBuilder.semAllEmotions;
import machineLearning.SentenceExampleBuilder.semEmotions;

import rainbownlp.analyzer.evaluation.CrossValidation;
import rainbownlp.analyzer.evaluation.Evaluator;
import rainbownlp.core.FeatureValuePair;
import rainbownlp.core.PhraseLink;
import rainbownlp.i2b2.sharedtask2012.LinkExampleBuilder;
import rainbownlp.machineLearning.ILearnerEngine;
import rainbownlp.machineLearning.MLExample;
import rainbownlp.machineLearning.MLExampleFeature;
import rainbownlp.machineLearning.SVMMultiClass;
import rainbownlp.machineLearning.SemEvalSVMMultiClass;
import rainbownlp.util.FileUtil;
import rainbownlp.util.HibernateUtil;

public class SemEmotionClassifier  implements ILearnerEngine  {
	public static final String experimentgroup = "BinaryLinkClassifier";
	
	
	public static void main(String[] args) throws Exception
	{
		FileUtil.logLine("/tmp/log.txt", "*******************\n**************************************");
		List<MLExample> alltestExamples = 
			MLExample.getAllExamples(SentenceExampleBuilder.experimentGroup, false);
		
//		FeatureValuePair.resetIndexes();
		
		for (semEmotions emotion:semEmotions.values())
		{
			FileUtil.logLine("/tmp/log.txt", emotion.toString());
			List<MLExample> trainExamples = getEmotionRelatedExamples(emotion,true);
			List<MLExample> testExamples = getEmotionRelatedExamples(emotion,false);
			
			SemEvalSVMMultiClass binary_cl = (SemEvalSVMMultiClass) 
					SemEvalSVMMultiClass.getLearnerEngine(SentenceExampleBuilder.experimentGroup);
			binary_cl.setTaskName(emotion.toString());
			binary_cl.train(trainExamples);
			binary_cl.test(testExamples);
//			
//			SVMMultiClass blc = (SVMMultiClass)
//				SVMMultiClass.getLearnerEngine(emotion.toString());
//			CrossValidation cv = new CrossValidation(blc);
////	
//			cv.crossValidation(trainExamples, 2).printResult();
			Evaluator.getEvaluationResult(testExamples).printResult();
			
		}
		FileUtil.logLine("/tmp/log.txt", "#######################################");
		Evaluator.getEvaluationResult(alltestExamples).printResult();
	}
	private static List<MLExample> getEmotionRelatedExamples(semEmotions emotion,boolean forTrain) {
		List<MLExample> e_examples = new ArrayList<MLExample>();
		List<MLExample> trainExamples = 
			MLExample.getAllExamples(SentenceExampleBuilder.experimentGroup, forTrain);
		for (MLExample example:trainExamples)
		{
			int expected = example.getExpectedClass();
			if (expected == emotion.ordinal() ||
					expected == semAllEmotions.valueOf("NOT_"+emotion.toString()).ordinal())
				e_examples.add(example);
		}
		return e_examples;
		
	}
	SVMMultiClass svm = (SVMMultiClass) SVMMultiClass.getLearnerEngine(experimentgroup);
	
	 @Override
	public void train(List<MLExample> exampleForTrain) throws IOException
	 {
		 if(exampleForTrain.size()==0) return;
		 
		 if(exampleForTrain.get(0).getCorpusName().equals(experimentgroup))
		 {//input is binary example
			svm.train(exampleForTrain);
		 }else
		 {
		 	 List<MLExample> binary_examples = new ArrayList<MLExample>();
			 for(MLExample example : exampleForTrain)
			 {
				 MLExample binary_example = 
					 MLExample.getInstanceForLink(example.getRelatedPhraseLink(), experimentgroup);
				 int expected_class_binary = 0;
				 if(example.getExpectedClass()!=PhraseLink.LinkType.UNKNOWN.ordinal())
					 expected_class_binary = 1;
				 
				 binary_example.setExpectedClass(expected_class_binary);
				 HibernateUtil.save(binary_example);
				 
				 binary_examples.add(binary_example);
			 }
			 
			 svm.train(binary_examples);
		 }
	 }

	@Override
	public void test(List<MLExample> pTestExamples) throws Exception {
		if(pTestExamples.size()==0) return;
		 
		 if(pTestExamples.get(0).getCorpusName().equals(experimentgroup))
		 {//input is binary example
			svm.test(pTestExamples);
		 }else
		 {
			List<MLExample> binary_examples = new ArrayList<MLExample>();
			for(int i=0;i< pTestExamples.size();i++)
				{
				 MLExample original_example =
					 pTestExamples.get(i);
				 MLExample binary_example = 
					 MLExample.getInstanceForLink(original_example.getRelatedPhraseLink(), experimentgroup);
				 
				 binary_example.setPredictedClass(-1);
				 HibernateUtil.save(binary_example);
				 
				 binary_examples.add(binary_example);
			 }
			 
			 svm.test(binary_examples);
			 
			 for(int i=0;i< pTestExamples.size();i++)
			 {
				 MLExample binary_example = 
					binary_examples.get(i);
				 MLExample original_example =
					 pTestExamples.get(i);
				 
				 if(binary_example.getPredictedClass() == 0)
				 {
					 original_example.setPredictedClass(PhraseLink.LinkType.UNKNOWN.ordinal());
				     HibernateUtil.save(original_example);
				 }
			 }
		 }
	}
}
